<template>
  <div class="flow_main">
    <div class="flow_node_template">
      <div class="head">
        <div class="head_title">
          <p>节点列表</p>
        </div>
      </div>
      <div id="node_list" class="node_list">
        <div class="flow_node" style="top:10px;left:20px;" data-code="1001" data-nodetype="1">
          <span class="badge">
            <i class="el-icon-caret-right" />
          </span>
          <span>开始</span>
        </div>
        <div class="flow_node" style="top:10px;left:20px;" data-code="1002" data-nodetype="2">
          <span class="badge">
            <i class="el-icon-circle-check" />
          </span>
          <span>结束</span>
        </div>
        <div class="flow_node" style="top:10px;left:20px;" data-code="1004" data-nodetype="3">
          <span class="badge">
            <i class="el-icon-share ico-separate-node" style="transform: rotate(90deg)" />
          </span>
          <span>分流</span>
        </div>
        <div class="flow_node" style="top:10px;left:20px;" data-code="1007" data-nodetype="4">
          <span class="badge">
            <i class="el-icon-share ico-merge-node" />
          </span>
          <span>合并</span>
        </div>
        <div class="flow_node" style="top:10px;left:20px;" data-code="1007" data-nodetype="5">
          <span class="badge">
            <i class="el-icon-star-on" />
          </span>
          <span>常规</span>
        </div>
      </div>
    </div>
    <div class="property_panel" id="node_property">
      <div class="head">
        <div class="head_title pro_title">
          <p>节点属性</p>
        </div>
      </div>
      <div class="property_container">
        <el-form ref="form" :model="nodeProperty" label-width="60px">
          <el-form-item label="名称">
            <el-input v-model="nodeProperty.name"></el-input>
          </el-form-item>
          <el-form-item label="规则">
            <el-input v-model="nodeProperty.ruleId"></el-input>
          </el-form-item>
          <el-form-item label="逻辑" v-show="nodeProperty.nodeType===4">
            <el-select v-model="nodeProperty.logic" placeholder="请选择逻辑类型">
              <el-option label="且" value="1"></el-option>
              <el-option label="或" value="2"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="清空" v-show="nodeProperty.logic==='2'">
            <el-switch v-model="nodeProperty.orClear"></el-switch>
          </el-form-item>
          <el-form-item label="备注">
            <el-input type="textarea" v-model="nodeProperty.remarks"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmitNode">更新</el-button>
            <el-button>取消</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <div class="property_panel" id="line_property">
      <div class="head">
        <div class="head_title pro_title">
          <p>属性列表</p>
        </div>
      </div>
      <div class="property_container">
        <el-form ref="form" :model="lineProperty" label-width="60px">
          <el-form-item label="名称">
            <el-input v-model="lineProperty.name"></el-input>
          </el-form-item>
          <el-form-item label="编码">
            <el-input v-model="lineProperty.code"></el-input>
          </el-form-item>
          <el-form-item label="备注">
            <el-input type="textarea" v-model="lineProperty.remarks"></el-input>
          </el-form-item>
          <el-form-item>
            <el-button type="primary" @click="onSubmitLine">更新</el-button>
            <el-button>取消</el-button>
          </el-form-item>
        </el-form>
      </div>
    </div>
    <div class="flow_container" id="flow_container">
      <div class="flow_canvas" id="flow_canvas"></div>
      <div class="right_menu" id="nodeRightMenu" style="display:none;cursor:default;position:absolute;z-index:500;">
        <ul class="submenu" style="list-style: none; padding: 5px 0px; margin: 0px; background-color: rgb(255, 255, 255); border: 1px solid rgb(90, 99, 119); width: 100px; min-width: 150px;">
          <li id="nodeProperty">
            <i class="icon-cog"></i>&nbsp;<span class="_label">属性</span>
          </li>
          <li id="pmDelete">
            <i class="icon-trash"></i>&nbsp;<span class="_label">删除</span>
          </li>
        </ul>
      </div>
      <div class="right_menu" id="lineRightMenu" style="display:none;cursor:default;position:absolute;z-index:500;">
        <ul class="submenu" style="list-style: none; padding: 5px 0px; margin: 0px; background-color: rgb(255, 255, 255); border: 1px solid rgb(90, 99, 119); width: 100px; min-width: 150px;">
          <li id="editConnectLabel">
            <i class="icon-edit"></i>&nbsp;<span class="_label">编辑</span>
          </li>
          <li id="delConnect">
            <i class="icon-remove"></i>&nbsp;<span class="_label">删除</span>
          </li>
        </ul>
      </div>
    </div>
  </div>
</template>

<script>
import $ from '../../../utils/jquery-1.7.2.min.js'
import '../../../utils/jquery-ui-1.9.2-min'
import '../../../utils/jquery.mousewheel.min'

export default {
  name: 'DesignIndex',
  data () {
    return {
      flowChartId: 0, // 流程图Id
      currentNodeId: -1, // 当前操作节点的id
      currentLineId: -1, // 当前操作线的Id
      width: 0,
      height: 0,
      loading: false,
      zoom: 1.0,
      nodeProperty: {},
      lineProperty: {},
      kmFlow: null
    }
  },
  created () {
    const id = this.$route.params.id
    if (id !== null && id !== '' && id !== undefined) {
      this.flowChartId = id
    } else {
      this.$message.error('参数不能为空')
    }
  },
  methods: {
    displayProperty: function (displayId, hideId) {
      if (!$(hideId).is(':hidden')) {
        $(hideId).animate({ width: '0px' }, function () {
          $(hideId).css('display', 'none')
        })
      }
      if (displayId.length > 0) {
        $(displayId).css('display', 'block').animate({ width: '300px' })
      }
    },
    displayNodeProperty: function () {
      debugger
      const context = this
      this.$requestx.get('/api/node/get?id=' + this.currentNodeId).then(res => {
        debugger
        res.logic = res.logic.toString()
        context.nodeProperty = res
        context.displayProperty('#node_property', '#line_property')
      })
    },
    displayLineProperty: function () {
      const context = this
      this.$requestx.get('/api/line/get?id=' + this.currentLineId).then(res => {
        context.lineProperty = res
        context.displayProperty('#line_property', '#node_property')
      })
    },
    onSubmitNode () {
      const context = this
      this.$requestx.put(
        '/api/node/update?id=' + this.currentNodeId,
        this.nodeProperty
      ).then(res => {
        $(context.kmFlow.activeNode).children().eq(1).html(context.nodeProperty.name)
        context.displayProperty('', '#node_property')
        context.$message({
          message: '操作成功',
          type: 'success'
        })
      })
    },
    onSubmitLine () {
      const context = this
      this.$requestx.put(
        '/api/line/update?id=' + this.currentLineId,
        this.lineProperty
      ).then(res => {
        context.kmFlow.activeNode.setLabel(context.lineProperty.name)
        context.displayProperty('', '#line_property')
        context.$message({
          message: '操作成功',
          type: 'success'
        })
      })
    },
    // 获取流程图中所有节点
    getNodeList: function () {
      return this.$requestx.get('/api/node/gets?id=' + this.flowChartId)
    },
    // 获取流程图中所有的线
    getLineList: function () {
      return this.$requestx.get('/api/line/gets?id=' + this.flowChartId)
    },
    // 添加节点
    AddNodeApi: function (node) {
      return this.$requestx.post('/api/node/add', node)
    },
    // 添加线
    AddLineApi: function (line) {
      return this.$requestx.post('/api/line/add', line)
    },
    // 删除一个节点
    DeleteNodeApi: function () {
      return this.$requestx.delete('/api/node/delete?id=' + this.currentNodeId)
    },
    // 删除一条线
    DeleteLineApi: function (lineId) {
      if (lineId === undefined) lineId = this.currentLineId
      return this.$requestx.delete('/api/line/delete?id=' + lineId)
    },
    // 更新节点的位置
    UpdateNodePositionApi: function (node) {
      return this.$requestx.put(
        '/api/node/updateposition?id=' + this.currentNodeId,
        node
      )
    },
    // 更新节点的信息
    UpdateNodeApi: function (node) {
      return this.$requestx.put(
        '/api/node/update?id=' + this.currentNodeId,
        node
      )
    },
    // 更新线的信息
    UodateLineApi: function (line) {
      return this.$requestx.put(
        '/api/line/update?id=' + this.currentLineId,
        line
      )
    }
  },
  mounted () {
    const vueInstance = this
    const jsPlumb = this.$jsPlumb
    const flowDiv = document.getElementById('flow_canvas')
    var KmFlow = function (ele, opt) {
      const pdiv = document.getElementById('flow_container')
      this.diffLeft = (10000 - pdiv.clientWidth) / 2
      this.diffTop = (5000 - pdiv.clientHeight) / 2
      this.$element = $(ele)
      this.activeNode = null // 右击时，保存上下文
      this.defaults = {
        canvasMenusEvent: {
          // 删除连接事件
          delConnect () {
            vueInstance
              .$confirm('确定删除该链接吗？', '提示', {
                confirmButtonText: '确定',
                cancelButtonText: '取消',
                type: 'warning'
              })
              .then(() => {
                vueInstance.DeleteLineApi().then(res => {
                  vueInstance.kmFlow.delLine(vueInstance.kmFlow.activeNode)
                  vueInstance.$message({
                    type: 'success',
                    message: '删除成功!'
                  })
                })
              })
          },
          // 删除节点事件
          pmDelete () {
            if (confirm('确定该节点删除吗？')) {
              const nodeHtmlId = $(vueInstance.kmFlow.activeNode).attr('id')
              $.each(jsPlumb.getAllConnections(), (_i, ele) => {
                if (
                  ele.sourceId === nodeHtmlId ||
                  ele.targetId === nodeHtmlId
                ) {
                  vueInstance.DeleteLineApi(ele.scope).then(res => {
                    vueInstance.kmFlow.delLine(ele)
                  })
                }
              })
              vueInstance.DeleteNodeApi().then(res => {
                // 从页面中移除节点
                $(vueInstance.kmFlow.activeNode).animate(
                  { opacity: 0 },
                  function () {
                    $(this).remove()
                  }
                )
              })
            }
          },
          // 右击节点 属性
          nodeProperty () {
            vueInstance.displayNodeProperty()
          },
          // 右击标签 属性
          editConnectLabel () {
            // 弹出界面
            vueInstance.displayLineProperty()
          }
        },
        // 这是连接线路的绘画样式
        connectorPaintStyle: {
          strokeWidth: 3,
          stroke: '#49afcd',
          joinstyle: 'round'
        },
        // 鼠标经过样式
        connectorHoverStyle: {
          strokeWidth: 3,
          stroke: '#da4f49'
        },
        // 流程设计器菜单
        lineRightMenu: '#lineRightMenu',
        // 节点菜单
        nodeRightMenu: '#nodeRightMenu',
        // 节点样式名称
        nodeStyleName: 'nodeStyle',
        labelclass: 'component label'
      }
      this.options = $.extend({}, this.defaults, opt)
    }
    KmFlow.prototype = {
      init: function () {
        this._initjsPlumbPlugIn()
        this._setMenu()
        this._initData()
        this._init()
        return this
      },
      // 初始化第三方插件
      _initjsPlumbPlugIn: function () {
        var context = this
        jsPlumb.importDefaults({
          Connector: 'Flowchart',
          DragOptions: { cursor: 'pointer' },
          EndpointStyle: { fill: '#225588' },
          Endpoint: ['Dot', { radius: 1 }],
          ConnectionOverlays: [['Arrow', { location: 1 }]],
          PaintStyle: context.options.connectorPaintStyle,
          Anchor: 'Continuous',
          ConnectorZIndex: 5,
          HoverPaintStyle: context.options.connectorHoverStyle
        })
        jsPlumb.setContainer(context.$element.attr('id'))
        jsPlumb.bind('contextmenu', function (c, e) {
          // 线的右击菜单
          if (c.type === undefined) {
            e.preventDefault()
            // 同时只显示一个菜单
            $(context.options.nodeRightMenu).hide()
            $(context.options.lineRightMenu)
              .css({ left: e.pageX + 'px', top: e.pageY + 'px' })
              .show()
            context.activeNode = c
            vueInstance.currentLineId = c.scope
            e.stopPropagation()
            return false
          }
        })
      },
      // 初始化数据
      _initData: function () {
        const context = this
        vueInstance.getNodeList().then(nodeList => {
          // 清除原有数据
          $('#flow_canvas').html('')
          $.each(nodeList, (_i, e) => {
            context.addNode({
              id: e.id,
              flowId: e.flowChartId,
              nodeType: e.nodeType,
              description: '',
              nodeName: e.name,
              icon: context.getIco(e.nodeType),
              logic: e.logic,
              ruleId: e.ruleId,
              orClear: e.orClear,
              separateNodeId: e.separateNodeId,
              style: `min-width:121px;height:36px;line-height:41px;color:#0e76a8;left:${context.diffLeft +
                e.positionX}px;top:${context.diffTop + e.positionY}px;`
            })
          })
          vueInstance.getLineList().then(lineList => {
            if (lineList.length > 0) {
              $.each(lineList, (_index, ele) => {
                context.connection(
                  `window${ele.tailNodeId}`,
                  `window${ele.headNodeId}`,
                  ele.id,
                  ele.name,
                  '备注',
                  ele.lineType
                )
              })
            }
          })
        })
      },
      // 设置设计器中右击菜单
      _setMenu: function () {
        const context = this
        this._setMenuItemEvent(this.options.canvasMenusEvent)
        this._bindNodeRightNodeMenu()
        $(this.$element).mousedown(function (e) {
          context.hideMenu()
          if (e.button === 0) {
            $('.property_panel').animate({ width: '0px' }, function () {
              $('.property_panel').css('display', 'none')
            })
          }
          return false
        })
      },
      // 节点绑定右击菜单
      _bindNodeRightNodeMenu: function () {
        const context = this
        $(this.$element).on(
          'contextmenu',
          '.' + this.options.nodeStyleName,
          function (e) {
            e.preventDefault()
            context.activeNode = this
            // 同时只显示一个菜单
            $(context.options.lineRightMenu).hide()
            $(context.options.nodeRightMenu)
              .css({ left: e.pageX + 'px', top: e.pageY + 'px' })
              .show()
            e.stopPropagation()
            return false
          }
        )
      },
      // 给右击菜单绑定点击事件
      _setMenuItemEvent: function (list) {
        var context = this
        $.each(list, function (id, func) {
          $('#' + id).click(function (e) {
            $(context.options.lineRightMenu).hide()
            $(context.options.nodeRightMenu).hide()
            func(e, context.activeNode) // 第一个参数，第二个是上下文
          })
        })
      },
      // 初始化一些样式
      _init: function () {
        $('#flow_canvas')
          .css('left', -this.diffLeft + 'px')
          .css('top', -this.diffTop + 'px')
        $('#flow_canvas').draggable()
        $('#node_list div')
          .draggable()
          .mouseup(function (e) {
            if (e.button === 0) {
              // const source = $(this)
              // const type = source.data('nodetype')
              const nodeInfo = vueInstance.kmFlow.createNodeJson($(this))
              const newNode = {
                id: 0,
                flowId: nodeInfo.flowChartId,
                nodeType: nodeInfo.nodeType,
                description: '',
                nodeName: nodeInfo.name,
                icon: vueInstance.kmFlow.getIco(nodeInfo.nodeType),
                logic: nodeInfo.logic,
                ruleId: nodeInfo.ruleId,
                orClear: nodeInfo.orClear,
                separateNodeId: nodeInfo.separateNodeId,
                style: `min-width:121px;height:36px;line-height:41px;color:#0e76a8;left:${vueInstance
                  .kmFlow.diffLeft + nodeInfo.positionX}px;top:${vueInstance
                    .kmFlow.diffTop + nodeInfo.positionY}px;`
              }
              vueInstance.AddNodeApi(nodeInfo).then(res => {
                newNode.id = res
                vueInstance.kmFlow.addNode(newNode)
                // vueInstance.displayNodeProperty()
              })
              $(this).css({ top: '10px', left: '20px' })
            }
          })
      },
      createNodeJson: function (obj) {
        const position = obj.offset()
        if (obj) {
          return {
            // "node_id":0,
            id: obj.attr('process_id'),
            name: obj
              .children('span')
              .text()
              .trim(),
            nodeType: obj.data('nodetype'),
            orClear: false,
            separateNodeId: 0,
            flowChartId: vueInstance.flowChartId,
            ruleId: 0,
            positionX: position.left - 440,
            positionY: position.top - 131
          }
        }
        return {}
      },
      // 获取节点Ico
      getIco: function (type) {
        switch (type) {
          case 1:
            return 'el-icon-caret-right'
          case 2:
            return 'el-icon-circle-check'
          case 3:
            return 'el-icon-share ico-separate-node'
          case 4:
            return 'el-icon-share ico-merge-node'
          case 5:
            return 'el-icon-star-on'
          default:
        }
      },
      // 设置位置
      setLocal: function (e) {
        if (e.button === 0) {
          const nodePosition = vueInstance.kmFlow.createNodeJson($(this))
          if (vueInstance.currentNodeId !== -1) { vueInstance.UpdateNodePositionApi(nodePosition) }
        }
      },
      // 添加一个节点
      addNode: function (node) {
        var context = this
        if (node.id <= 0) {
          return false
        }
        var nodeId = 'window' + node.id
        var badge = 'badge-inverse'
        var icon = 'el-icon-star-on'
        if (node.icon) {
          icon = node.icon
        }
        var nodeDiv = $('<div data-nodetype=' + node.nodeType + '></div>')
        nodeDiv
          .attr('id', nodeId)
          .attr('description', node.description)
          .attr('logic', node.logic)
          .attr('rule_id', node.ruleId)
          .attr('or_clear', node.orClear)
          .attr('separate_node_id', node.separateNodeId)
          .attr('style', node.style)
          .attr('process_to', node.process_to)
          .attr('process_id', node.id)
          .attr('time_limited_type', node.time_limited_type)
          .css({
            position: 'absolute',
            'z-index': '9',
            cursor: 'move',
            'min-width': '121px',
            'line-height': '35px'
          })
          .addClass(context.options.nodeStyleName + ' flow_node')
          .html(
            `<span id="span${nodeId}" class="process-flag badge ${badge} "><i class="${icon}"></i></span>&nbsp;<span>${node.nodeName}</span>`
          )
        $(context.$element).append(nodeDiv)

        // 使之可拖动 和 连线
        jsPlumb.draggable(jsPlumb.getSelector('#' + nodeId), {
          // 使节点不能移出div
          containment: 'parent'
        })
        context.initEndPoints(nodeId)
        // 使可以连接线
        jsPlumb.makeTarget(jsPlumb.getSelector('#' + nodeId), {
          dropOptions: { hoverClass: 'hover', activeClass: 'active' },
          anchor: 'Continuous',
          maxConnections: -1,
          endpoint: ['Dot', { radius: 1 }],
          paintStyle: { fillStyle: '#ec912a', radius: 1 },
          hoverPaintStyle: context.options.connectorHoverStyle,
          beforeDrop: function (params) {
            context.beforeDrop(params)
          }
        })
        context.activeNode = nodeDiv[0]
        nodeDiv.mouseup(context.setLocal)
        nodeDiv.mousedown((e, c) => {
          context.activeNode = e.currentTarget
          vueInstance.currentNodeId = $(vueInstance.kmFlow.activeNode).attr(
            'process_id'
          )
        })
        nodeDiv.mouseup(() => {
          context.activeNode = null
        })
        return true
      },
      // 线连接的检查事件
      beforeDrop: function (params) {
        // 此方法始终返回false 这样连线可以确保在API保持成功之后再连接
        const sourceId = params.sourceId.replace('span', '')
        const targetId = params.targetId
        if (sourceId === targetId) {
          alert('不能连接自己')
          return false
        }
        let isRepeated = false
        $.each(jsPlumb.getAllConnections(), (_i, ele) => {
          if (ele.sourceId === sourceId && ele.targetId === targetId) {
            isRepeated = true
            return false
          }
        })
        if (isRepeated) {
          alert('步骤连接重复')
          return false
        }
        this._saveLine(params)
        return false
      },
      _saveLine: function (params) {
        // 连接成功后调用方法
        const jsonLine = {
          id: 0,
          flowChartId: vueInstance.flowChartId,
          headNodeId: params.targetId.replace('window', ''),
          tailNodeId: params.sourceId.replace('window', '').replace('span', ''),
          lineType: 1,
          name: '下一步'
        }
        const context = this
        vueInstance.AddLineApi(jsonLine).then(res => {
          jsonLine.id = res
          context.connection(
            `window${jsonLine.tailNodeId}`,
            `window${jsonLine.headNodeId}`,
            jsonLine.id,
            jsonLine.name,
            jsonLine.lineType
          )
        })
          .catch(err => {
            vueInstance.$message.error(err)
          })
      },
      // 使得节点之间可以连线
      initEndPoints: function (nodeId) {
        var connectorHoverStyle = this.options.connectorHoverStyle
        var connectorPaintStyle = this.options.connectorPaintStyle
        $('#' + nodeId + ' .process-flag').each(function (i, e) {
          var p = $(e).parent()
          jsPlumb.makeSource($(e), {
            parent: p,
            anchor: 'Continuous',
            endpoint: ['Dot', { radius: 1 }],
            connector: ['Flowchart', { stub: [5, 5] }],
            connectorStyle: connectorPaintStyle,
            hoverPaintStyle: connectorHoverStyle,
            dragOptions: {},
            maxConnections: -1
          })
        })
      },
      // 设置线的标签
      setLabel: function (e, t) {
        e.setLabel({
          label: t,
          location: 0.5,
          id: 'Label',
          cssClass: this.options.labelclass
        })
      },
      // 隐藏右键菜单
      hideMenu: function () {
        $(this.options.lineRightMenu).hide()
        $(this.options.nodeRightMenu).hide()
      },
      // 删除连线
      delLine: function (line) {
        jsPlumb.deleteConnection(line)
      },
      // 连线
      connection: function (
        source,
        target,
        scope,
        label,
        description,
        linetype
      ) {
        if ($('#' + source).length > 0 && $('#' + target).length > 0) {
          var line = jsPlumb.connect({
            source: source,
            target: target,
            scope: scope.toString(),
            linetype: linetype
          })
          $(line).attr('description', description)
          this.setLabel(line, label)
        } else {
          console.log(source + ' 或 ' + target + ' 节点不存在')
        }
      }
    }

    window.setZoom = function (zoom, instance, transformOrigin, el) {
      transformOrigin = transformOrigin || [0.5, 0.5]
      instance = instance || jsPlumb
      el = el || instance.getContainer()
      var p = ['webkit', 'moz', 'ms', 'o']
      var s = 'scale(' + zoom + ')'
      var oString =
          transformOrigin[0] * 100 + '% ' + transformOrigin[1] * 100 + '%'

      for (var i = 0; i < p.length; i++) {
        el.style[p[i] + 'Transform'] = s
        el.style[p[i] + 'TransformOrigin'] = oString
      }

      el.style.transform = s
      el.style.transformOrigin = oString

      instance.setZoom(zoom)
    }

    $(() => {
      $('#flow_canvas').mousewheel(function (e, direction) {
        vueInstance.zoom = vueInstance.zoom + direction * 0.05
        if (vueInstance.zoom < 0.13) {
          vueInstance.zoom = 0.13
        }
        window.setZoom(vueInstance.zoom)
        return false
      })
      vueInstance.kmFlow = new KmFlow(flowDiv, {})
      vueInstance.kmFlow.init()
      // 隐藏右击菜单
      $('#nodeRightMenu li,#lineRightMenu li').click(function () {
        vueInstance.kmFlow.hideMenu()
      })
    })
  }
}
</script>
<style lang="less" scoped>
.flow_main {
  height: 100%;
  overflow: auto;
  overflow-x: hidden;
}
.head {
  font-weight: bold;
  text-align: center;
  background-color: white;
  width: 100%;
  height: 30px;
  .head_title {
    // line-height: 30px;
    cursor: default;
  }
  .pro_title {
    border-bottom: 1px solid gray;
  }
}

.flow_node_template {
  cursor: default;
  float: left;
  width: 200px;
  position: relative;
  z-index: 99;
  background-color: white;
  height: 600px;
}

.div_button_save {
  margin-top: 15px;
  text-align: right;
}
//属性面板
.property_panel {
  width: 0px;
  height: 100%;
  float: right;
  background-color: white;
  box-shadow: #0e90d2;
  overflow: auto;
  position: relative;
  overflow-y: auto !important;
  display: none;
}
//属性面板的容器
.property_container {
  font-size: 12px;
  padding: 30px 10px;
}
.property_container > div {
  margin-left: 25px;
  margin-right: 25px;
}
.property_container p {
  margin-top: 10px;
}
// 流程的画布容器
.flow_container {
  z-index: -1;
  height: 100%;
  //cursor: not-allowed;
  overflow: auto;
  overflow: hidden;
  position: inherit;
  background: rgb(58, 65, 68) url(../../../assets/img/grid.png) repeat;
}
//流程的画布
.flow_canvas {
  z-index: 1;
  width: 10000px;
  height: 5000px;
  overflow: hidden;
  position: relative;
  left: -5000px;
  top: -2500px;
}
//节点和连线的右击菜单
.right_menu li {
  margin: 0px;
  color: rgb(51, 51, 51);
  display: block;
  cursor: default;
  padding: 5px 40px 5px 20px;
  border: 0px;
  background-color: rgba(0, 0, 0, 0);
  font-family: verdana;
}

.right_menu li:hover {
  margin: 0px;
  color: rgb(255, 255, 255);
  display: block;
  cursor: default;
  padding: 5px 40px 5px 20px;
  border: 0px;
  background-color: rgb(90, 99, 119);
  font-family: verdana;
}
</style>

<style>
.flow_container {
  cursor: default;
}
.flow_container .label {
  display: inline-block;
  padding: 2px 4px;
  font-size: 12px;
  font-weight: bold;
  line-height: 14px;
  color: #ffffff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
  white-space: nowrap;
  vertical-align: baseline;
  background-color: #999999;
  -webkit-border-radius: 3px;
  -moz-border-radius: 3px;
  border-radius: 3px;
}
.badge {
  display: inline-block;
  padding: 4px 9px;
  font-size: 12px;
  font-weight: bold;
  line-height: 14px;
  color: #ffffff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
  white-space: nowrap;
  vertical-align: baseline;
  -webkit-border-radius: 9px;
  -moz-border-radius: 9px;
  border-radius: 9px;
  background-color: #333333;
  margin-right: 10px;
  z-index: 1000;
}
.flow_node {
  cursor: move;
  width: 120px;
  height: 30px;
  line-height: 35px;
  position: relative;
  z-index: 99;
  top: 10px;
  left: 20px;
  text-align: left;
  padding-left: 10px;
  font-size: 12px;
  border-radius: 3px;
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2),
    0 1px 2px rgba(0, 0, 0, 0.05);
  border-bottom-color: #b3b3b3;
  border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
  background-repeat: repeat-x;
  border: 1px solid #cccccc;
  text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
  vertical-align: middle;
  display: inline-block;
  margin-bottom: 0;
  background-color: #f5f5f5;
  animation-name: diminish;
  animation-fill-mode: forwards;
  animation-duration: 0.5s;
  animation-timing-function: inherit;
}
.ico-separate-node {
  transform: rotate(90deg);
}
.ico-merge-node {
  transform: rotate(-90deg);
}
@keyframes diminish {
  0% {
    transform: scale(1.1, 1.1);
  }

  100% {
    transform: scale(1, 1);
  }
}
@keyframes largen {
  0% {
    transform: scale(1, 1);
  }

  100% {
    transform: scale(1.2, 1.2);
  }
}

.node_list div {
  color: rgb(14, 118, 168);
  width: 120px;
  height: 35px;
  line-height: 35px;
  position: relative;
  z-index: 999;
  margin-top: 20px;
  cursor: move;
  min-width: 100px;
  animation-name: diminish;
  animation-fill-mode: forwards;
  animation-duration: 0.3s;
  animation-timing-function: inherit;
}
.node_list div:hover {
  animation-name: largen;
  animation-fill-mode: forwards;
  animation-duration: 0.5s;
  animation-timing-function: inherit;
}
.flow_node:hover {
  animation-name: largen;
  animation-fill-mode: forwards;
  animation-duration: 0.5s;
  animation-timing-function: inherit;
}
</style>
